﻿using System;
using System.Data;
using System.Data.Common;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Formatters.Binary;
using System.IO;
using System.Collections;

namespace BO
{

    //class BinDataTableApp
    //{
    //    [STAThread]
    //    static void Main(string[] args)
    //    {
    //        // Get a DataTable from Northwind
    //        /* --- */
    //        Console.WriteLine("Downloading data from Northwind...");
    //        SqlDataAdapter adapter = new SqlDataAdapter(
    //            "SELECT * FROM [Order Details]",
    //            "DATABASE=northwind;SERVER=localhost;UID=sa;");
    //        BinDataTable dt = new BinDataTable("MyTestTable");
    //        adapter.Fill(dt);
    //        /* --- */
    //        Console.WriteLine("Downloaded " + dt.Rows.Count.ToString() + " records...");
    //        /* --- */
    //        Console.WriteLine("Serializing to output_using_iser.dat...");

    //        // Serialize the Binary Data Table
    //        BinaryFormatter bf = new BinaryFormatter();
    //        StreamWriter swDat = new StreamWriter("output_using_iser.dat");
    //        bf.Serialize(swDat.BaseStream, dt);
    //        long size = swDat.BaseStream.Length;
    //        swDat.Close();
    //        /* --- */
    //        Console.WriteLine("Done. File size is " + size.ToString() + " bytes.");

    //        // Deserialize the Binary Data Table
    //        /* --- */
    //        Console.WriteLine("\n\nLoading from \"output_using_iser.dat\"...");
    //        BinDataTable dtRead = new BinDataTable("MyTestTable");
    //        BinaryFormatter bfRead = new BinaryFormatter();
    //        StreamReader sr = new StreamReader("output_using_iser.dat");
    //        dtRead = (BinDataTable)bfRead.Deserialize(sr.BaseStream);
    //        sr.Close();

    //        /* --- */
    //        Console.WriteLine("Done. Rows loaded are " + dtRead.Rows.Count.ToString());
    //        /* --- */
    //        Console.WriteLine("\nPress any key to stop.");
    //        Console.Read();
    //    }
    //}


    [Serializable]
    public class BinDataTable : DataTable, ISerializable
    {
        public BinDataTable()
            : base()
        {
        }
        public BinDataTable(string name)
            : base(name)
        {
        }


        protected BinDataTable(SerializationInfo si, StreamingContext context)
        {
            // DO NOT call the base ctor otherwise an ExceptionEx will be thrown

            /* --- */
            Console.WriteLine("----> Calling the \"BinDataTable\" serialization ctor");

            // Extract from the serialization info
            ArrayList colNames = new ArrayList();
            ArrayList colTypes = new ArrayList();
            ArrayList dataRows = new ArrayList();
            colNames = (ArrayList)si.GetValue("ColNames", typeof(ArrayList));
            colTypes = (ArrayList)si.GetValue("ColTypes", typeof(ArrayList));
            dataRows = (ArrayList)si.GetValue("DataRows", typeof(ArrayList));

            // Add columns
            for (int i = 0; i < colNames.Count; i++)
            {
                DataColumn col = new DataColumn(colNames[i].ToString(),
                    Type.GetType(colTypes[i].ToString()));
                col.Caption = col.ColumnName;
                this.Columns.Add(col);
            }

            // Add rows
            for (int i = 0; i < dataRows.Count; i++)
            {
                DataRow row = this.NewRow();
                row.ItemArray = (object[])dataRows[i];
                this.Rows.Add(row);
            }

            this.AcceptChanges();
        }

        void System.Runtime.Serialization.ISerializable.GetObjectData(SerializationInfo si, StreamingContext context)
        {
            /* --- */
            Console.WriteLine("----> Calling the \"BinDataTable\" GetObjectData method...");

            // DO NOT call the base method otherwise XML will slip into the data
            //base.GetObjectData(si, context);

            // Add arrays
            ArrayList colNames = new ArrayList();
            ArrayList colTypes = new ArrayList();
            ArrayList dataRows = new ArrayList();

            // Insert column information (names and types) into worker arrays
            foreach (DataColumn col in this.Columns)
            {
                colNames.Add(col.ColumnName);
                colTypes.Add(col.DataType.FullName);
            }

            // Insert rows information into a worker array
            foreach (DataRow row in this.Rows)
                dataRows.Add(row.ItemArray);

            // Add arrays to the serialization info structure
            /* --- */
            Console.WriteLine("----> Adding table data as ArrayList objects...");
            si.AddValue("ColNames", colNames);
            si.AddValue("ColTypes", colTypes);
            si.AddValue("DataRows", dataRows);
        }
    }
}